#ifndef HITTABLE_H
#define HITTABLE_H

#include "Ray.h"
#include "Interval.h"
#include "AABB.h"
class Material;
class Pdf;

class HitRecord {
  public:
    Point3 p;
    Vec3 normal;
    double t;
    double u;
    double v;
    bool front_face;
    std::shared_ptr<Material> material;
    void set_face_normal(const Ray& r, const Vec3& outward_normal);
};

class ScatterRecord {
public:
    Color attenuation;
    std::shared_ptr<Pdf> pdf_ptr;
    bool skip_pdf;
    Ray skip_pdf_ray;
};


class Hittable {
  public:
    virtual ~Hittable() = default;

    virtual bool hit(const Ray& r, Interval ray_t, HitRecord& rec) const = 0;

    //for light source,like Quad light source for sample Quad
    virtual double pdf_value(const Point3& origin, const Vec3& direction) const;

    virtual Vec3 random(const Point3& origin) const;

    virtual  AABB bounding_box()const = 0;
};


class TranslateHitable : public  Hittable
{
public:
    TranslateHitable(std::shared_ptr<Hittable> object, const Vec3& offset);

    bool hit(const Ray& r, Interval ray_t, HitRecord& rec) const override;

    AABB bounding_box() const override { return bbox; }
private:
    std::shared_ptr<Hittable> object;
    Vec3 offset;
    AABB bbox;
};

class RotateHittable : public Hittable
{
public:

    RotateHittable(std::shared_ptr<Hittable> object, double angle);

    bool hit(const Ray& r, Interval ray_t, HitRecord& rec) const override;

    AABB bounding_box() const override { return bbox; }

private:
    std::shared_ptr<Hittable> object;
    double sin_theta;
    double cos_theta;
    AABB bbox;
};
#endif
